package com.example.broadcast;

import cn.hutool.json.JSONObject;
import com.corundumstudio.socketio.AckRequest;
import com.corundumstudio.socketio.Configuration;
import com.corundumstudio.socketio.SocketIOClient;
import com.corundumstudio.socketio.SocketIOServer;
import com.corundumstudio.socketio.annotation.OnConnect;
import com.corundumstudio.socketio.annotation.OnDisconnect;
import com.corundumstudio.socketio.annotation.OnEvent;
import jakarta.annotation.PostConstruct;
import org.bytedeco.ffmpeg.global.avcodec;
import org.bytedeco.ffmpeg.global.avformat;
import org.bytedeco.ffmpeg.global.avutil;
import org.bytedeco.javacv.FFmpegFrameGrabber;
import org.bytedeco.javacv.FFmpegFrameRecorder;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.Map;

@SpringBootApplication
public class BroadcastApplication {

   /* private static final String TEMP_FILE_PATH = "/tmp/temp_video_stream.flv";
    private SocketIOServer server;*/

    public static void main(String[] args) {
        SpringApplication.run(BroadcastApplication.class, args);
    }

   /* @PostConstruct
    public void init() {
        Configuration config = new Configuration();
           config.setHostname("0.0.0.0");
        config.setPort(8081);

        server = new SocketIOServer(config);
        server.addEventListener("offer", String.class, this::onOffer);
        server.addEventListener("candidate", String.class, this::onCandidate);
        server.addEventListener("startStream", String.class, this::onStartStream);

        server.addConnectListener(this::onConnect);
        server.addDisconnectListener(this::onDisconnect);

        server.start();
        System.out.println("SocketIO server started on port 8081");
    }

    @OnConnect
    public void onConnect(SocketIOClient client) {
        System.out.println("Client connected: " + client.getSessionId());
    }

    @OnDisconnect
    public void onDisconnect(SocketIOClient client) {
        System.out.println("Client disconnected: " + client.getSessionId());
    }

    public void onOffer(SocketIOClient client, String data, AckRequest ackRequest) {
        System.out.println("Received offer from client: " + client.getSessionId());
        RTCPeerConnection pc = new RTCPeerConnection(client);
        pc.handleOffer(data);
    }

    public void onCandidate(SocketIOClient client, String data, AckRequest ackRequest) {
        System.out.println("Received candidate from client: " + client.getSessionId());
        RTCPeerConnection pc = RTCPeerConnection.getConnectionByClient(client);
        if (pc != null) {
            pc.handleCandidate(data);
        }
    }

    public void onStartStream(SocketIOClient client, String data, AckRequest ackRequest) {
        System.out.println("Received startStream request from client: " + client.getSessionId());
        RTCPeerConnection pc = RTCPeerConnection.getConnectionByClient(client);
        if (pc != null) {
            pc.startFFmpeg();
        }
    }

    public static class RTCPeerConnection {
        private static final java.util.Map<String, RTCPeerConnection> connections = new java.util.HashMap<>();
        private final SocketIOClient client;
        private FFmpegFrameGrabber grabber;
        private FFmpegFrameRecorder recorder;

        public RTCPeerConnection(SocketIOClient client) {
            this.client = client;
            connections.put(client.getSessionId().toString(), this);
        }

        public static RTCPeerConnection getConnectionByClient(SocketIOClient client) {
            return connections.get(client.getSessionId().toString());
        }

        public void handleOffer(String offer) {
            // 处理 offer
            // 这里可以生成 answer 并发送回客户端
            JSONObject data= new JSONObject();
            data.set("name","xrb");
            client.sendEvent("answer", offer);
        }

        public void handleCandidate(String candidate) {
            // 处理 candidate
        }

        public void startFFmpeg() {
            try {
                Files.deleteIfExists(Paths.get(TEMP_FILE_PATH));
                grabber = new FFmpegFrameGrabber(TEMP_FILE_PATH);
                recorder = new FFmpegFrameRecorder("rtmp://124.70.49.99:1935/live/stream", 640, 480);

                // 初始化抓取器和记录器
                grabber.start();
                recorder.start();

                // 循环读取帧并记录
                while (true) {
                    org.bytedeco.javacv.Frame frame = grabber.grabFrame();
                    if (frame == null) {
                        break;
                    }
                    recorder.record(frame);
                }

                // 停止抓取器和记录器
                grabber.stop();
                recorder.stop();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        public void processVideoStream(byte[] data) {
            try (FileOutputStream fos = new FileOutputStream(TEMP_FILE_PATH, true)) {
                fos.write(data);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }*/
}